package jhu.profiteer;

import java.io.IOException;
import jhu.profiteer.data.*;
import jhu.profiteer.data.Account;
import jhu.profiteer.data.AccountJpaController;
import jhu.profiteer.data.GameConfigurationParametersJpaController;

import jhu.profiteer.data.exceptions.NonexistentEntityException;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jhu.profiteer.data.CharacterJpaController;

/**
 * Servlet implementation class Character
 */
public class Character extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        HttpSession session = request.getSession();
        Vector<String> notices = (Vector<String>) session.getAttribute("notices");
        boolean characterFound = true;
        String url = "";

        // the servlet checks for a session attribute named �account�  of type Account
        Account account = (Account) session.getAttribute("account");
        String submit = request.getParameter("submit");
        notices = (Vector<String>)session.getAttribute("notices");
        String description = request.getParameter("description");

        if (null == account) {
            this.getServletContext().getRequestDispatcher("/index").forward(request, response);
            return;
        }

        //check for a session attribute named �character� of type Character.
        jhu.profiteer.data.Character character = (jhu.profiteer.data.Character) session.getAttribute("character");


        if (null == character) {


            //search the database for a Character with an accountId equal to the value of the id field in the Account object.
            CharacterJpaController cjc = new CharacterJpaController();
            if(cjc.testForCharacterWithAccountId(Long.parseLong(account.getId().toString()))) {
                character = cjc.findCharacter(Long.parseLong(account.getId().toString()));
            }
            else{
                 character = null;
            }

            if ((null == submit) || submit.isEmpty()) {
                this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);
                return;

            }

        }

        if (null == character) {
            if (submit.equalsIgnoreCase("Create Character")) {
                //if Character has been found
                if (null != character) {
                    this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);
                    return;
                }
                //if Character has NOT been found
                boolean save = true;

                String characterName = request.getParameter("characterName");

                if ((null == characterName) || characterName.isEmpty()) {
                    if (null == notices) {
                        notices = new Vector<String>();
                    }
                    notices.add("Please provide a character name.");
                    save = false;


                    if (null != notices) {
                        session.setAttribute("notices", notices);
                    }
                    this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);
                }

                String airplaneName = request.getParameter("airplaneName");

                if ((null == airplaneName) || airplaneName.isEmpty()) {
                    if (null == notices) {
                        notices = new Vector<String>();
                    }
                    notices.add("Please provide an airplane name.");
                    save = false;


                    if (null != notices) {
                        session.setAttribute("notices", notices);
                    }
                    this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);
                }


                if (save) {

                    //search the database for the sole GameConfigurationParameters object.
                    GameConfigurationParametersJpaController gcjc = new GameConfigurationParametersJpaController();
                    GameConfigurationParameters gcp = gcjc.findGameConfigurationParameters();


                    /* create a Character object,
                     * set the accountId field in the Character object to the value of the id field in the Account object,
                     * set the name field in the Character object to the value of the characterName request parameter,
                     * set the description field in the Character object to the value of the description request parameter,
                     * set the currentLocationId field in the Character object to the value of the initialLocationId field in the GameConfigurationParameters object,
                     * set the money field in the Character object to the value of the initialMoney field in the GameConfigurationParameters object.
                     */
                    character = new jhu.profiteer.data.Character();
                    character.setAccountId(account.getId());
                    character.setName(characterName);
                    if ((null != description) && !description.isEmpty()) {
                        character.setDescription(description);
                    }
                    character.setCurrentLocationId(gcp.getInitialLocationId());
                    character.setMoney(gcp.getInitialMoney());

                    /* should create an Airplane object,
                     * set the name field in the Airplane object to the value of the airplaneName request parameter,
                     * set the currentFuel and maxFuel fields in the Airplane object to the value of the initialFuel field in the GameConfigurationParameters object,
                     * and set the maxCargoCapacity field in the Airplane object to the value of the initialCargoCapacity field in the GameConfigurationParameters object.
                     */
                    Airplane airplane = new Airplane();
                    airplane.setName(airplaneName);
                    airplane.setCurrentFuel(gcp.getInitialFuel());
                    airplane.setMaxFuel(gcp.getInitialFuel());
                    airplane.setMaxCargoCapacity(gcp.getInitialCargoCapacity());

                    /* create a database transaction,
                     * save the Character object to the database,
                     * set the characterId field in the Airplane object to the value of the id field in the Character object,
                     * save the Airplane object to the database.
                     */
                    CharacterJpaController cjc = new CharacterJpaController();
                    //cjc.getEntityManager().getTransaction().begin();
                    cjc.create(character);
                    airplane.setCharacterId(character.getId());
                    AirplaneJpaController ajc = new AirplaneJpaController();
                    ajc.create(airplane);
                    //cjc.getEntityManager().getTransaction().commit();

                    LocationJpaController ljc = new LocationJpaController();
                    Location l = ljc.findLocation(character.getCurrentLocationId());
                    l.generateCurrentValues(character);

                    session.setAttribute("character", character);
                    session.setAttribute("airplane", airplane);



                    if (null == notices) {
                        notices = new Vector<String>();
                    }
                    notices.add("You have successfully created a character.");
                    url = "/characterInformation";



                }

                if (null != notices) {
                    session.setAttribute("notices", notices);
                }
                this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);

            }
        }
        if (null != character) {
            if (submit.equalsIgnoreCase("Update Description")) {
                //if Character has NOT been found
                if (null == character) {
                    this.getServletContext().getRequestDispatcher("/characterInformation").forward(request, response);
                    return;
                }


                if ((null == description) || description.isEmpty()) {
                    if (null == notices) {
                        notices = new Vector<String>();
                    }
                    notices.add("Please provide description.");
                    url = "/characterInformation";
                }
                if ((null != description) && !description.isEmpty()) {
                    /* set the description field in the Character object to the value of the description request parameter,
                     * create a database transaction,
                     * save the Character object to the database,
                     * and commit the transaction.
                     */
                    CharacterJpaController cjc = new CharacterJpaController();
                    character.setDescription(description);
                    //cjc.getEntityManager().getTransaction().begin();
                    try {
                        cjc.edit(character);

                        if (null == notices) {
                            notices = new Vector<String>();
                        }
                        notices.add("You have successfully updated the description.");
                    } catch (NonexistentEntityException nee) {
                        nee.printStackTrace();
                        notices.add("No character exists.");
                    } catch (Exception e) {
                        e.printStackTrace();
                        notices.add("Error editing character.");
                    }

                    //cjc.getEntityManager().getTransaction().commit();




                    url = "/characterInformation";
                }
                if (null != notices) {
                    session.setAttribute("notices", notices);
                }
                this.getServletContext().getRequestDispatcher(url).forward(request, response);
            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
